/*******************************************************************************
 * Copyright(c) 2023 Levetop Semiconductor Co.,Led. All rights reserved.
 * @file     sincos_table.c
 * @author   UartTFT Application Team
 * @version  V0.0.1
 * @date     2023-01-01
 * @brief
 ********************************************************************************/

#include "sincos_table.h"

const uint32_t SinCosTable[91][2] = {
	0,1000000,
	17452,999848,
	34899,999391,
	52336,998630,
	69756,997564,
	87156,996195,
	104528,994522,
	121869,992546,
	139173,990268,
	156434,987688,
	173648,984808,
	190809,981627,
	207912,978148,
	224951,974370,
	241922,970296,
	258819,965926,
	275637,961262,
	292372,956305,
	309017,951057,
	325568,945519,
	342020,939693,
	358368,933580,
	374607,927184,
	390731,920505,
	406737,913545,
	422618,906308,
	438371,898794,
	453990,891007,
	469472,882948,
	484810,874620,
	500000,866025,
	515038,857167,
	529919,848048,
	544639,838671,
	559193,829038,
	573576,819152,
	587785,809017,
	601815,798636,
	615661,788011,
	629320,777146,
	642788,766044,
	656059,754710,
	669131,743145,
	681998,731354,
	694658,719340,
	707107,707107,
	719340,694658,
	731354,681998,
	743145,669131,
	754710,656059,
	766044,642788,
	777146,629320,
	788011,615661,
	798636,601815,
	809017,587785,
	819152,573576,
	829038,559193,
	838671,544639,
	848048,529919,
	857167,515038,
	866025,500000,
	874620,484810,
	882948,469472,
	891007,453990,
	898794,438371,
	906308,422618,
	913545,406737,
	920505,390731,
	927184,374607,
	933580,358368,
	939693,342020,
	945519,325568,
	951057,309017,
	956305,292372,
	961262,275637,
	965926,258819,
	970296,241922,
	974370,224951,
	978148,207912,
	981627,190809,
	984808,173648,
	987688,156434,
	990268,139173,
	992546,121869,
	994522,104528,
	996195, 87156,
	997564, 69756,
	998630, 52336,
	999391, 34899,
	999848, 17452,
	1000000,0
};
const uint32_t tanTable[46] = {
	0,
	17455,
	34920,
	52407,
	69926,
	87488,
	105104,
	122784,
	140540,
	158384,
	176326,
	194380,
	212556,
	230868,
	249328,
	267949,
	286745,
	305730,
	324919,
	344327,
	363970,
	383864,
	404026,
	424474,
	445228,
	466307,
	487732,
	509525,
	531709,
	554309,
	577350,
	600840,
	624869,
	649407,
	674508,
	700207,
	726542,
	753554,
	781285,
	809784,
	839099,
	869286,
	900400,
	932515,
	965688,
	1000000
};

int32_t rangeAngle(int32_t angle, int32_t min, int32_t max)
{
	while (angle < min)
		angle += (max - min);
	while (angle > max)
		angle -= (max - min);
	return angle;
}
int32_t fast_sin(int32_t angle)
{
	angle=rangeAngle(angle,0,360);

	if (angle >= 0 && angle <= 90)
		return SinCosTable[angle][0];
	else if (angle >= 90 && angle <= 180)
		return SinCosTable[180 - angle][0];
	else if (angle >= 180 && angle <= 270)
		return -SinCosTable[angle - 180][0];
	else
		return -SinCosTable[360 - angle][0];
}
int32_t fast_cos(int32_t angle)
{
	angle=rangeAngle(angle,0,360);

	if (angle >= 0 && angle <= 90)
		return SinCosTable[angle][1];
	else if (angle >= 90 && angle <= 180)
		return -SinCosTable[180 - angle][1];
	else if (angle >= 180 && angle <= 270)
		return -SinCosTable[angle - 180][1];
	else
		return SinCosTable[360 - angle][1];
}
uint32_t fast_tan(int32_t angle)
{
	return tanTable[angle];
}
const uint32_t FastTanTable[]=
{
	0x00000000,0x000000AE,0x0000015D,0x0000020C,0x000002BB,0x0000036A,0x0000041B,0x000004CB,0x0000057D,0x0000062F,0x000006E3,0x00000797,0x0000084D,0x00000904,0x000009BD,0x00000A77,
	0x00000B33,0x00000BF1,0x00000CB1,0x00000D73,0x00000E37,0x00000EFE,0x00000FC8,0x00001094,0x00001164,0x00001237,0x0000130D,0x000013E7,0x000014C5,0x000015A7,0x0000168D,0x00001778,
	0x00001868,0x0000195E,0x00001A59,0x00001B5A,0x00001C61,0x00001D6F,0x00001E84,0x00001FA1,0x000020C6,0x000021F4,0x0000232C,0x0000246D,0x000025B8,0x00002710,0x00002873,0x000029E3,
	0x00002B62,0x00002CEF,0x00002E8D,0x0000303C,0x000031FF,0x000033D6,0x000035C3,0x000037C9,0x000039E9,0x00003C26,0x00003E83,0x00004102,0x000043A8,0x00004678,0x00004977,0x00004CAA,
	0x00005017,0x000053C5,0x000057BC,0x00005C06,0x000060AE,0x000065C2,0x00006B52,0x00007172,0x00007838,0x00007FC4,0x0000883A,0x000091C8,0x00009CAB,0x0000A932,0x0000B7C6,0x0000C8F5,
	0x0000DD88,0x0000F6A1,0x000115F1,0x00013E23,0x000173A7,0x0001BE7C,0x00022E9E,0x0002E95B,0x00045E9A,0x0008BDE4
};
uint32_t FastTan(uint8_t angle)
{
	if(angle>=90)
		return 0xffffffff;
	else 
		return FastTanTable[angle];		
}
const uint16_t FastAtanTable[]={
	0	,17	,35	,52	,70	,87	,105	,123	,141	,158	,
	176	,194	,213	,231	,249	,268	,287	,306	,325	,344	,
	364	,384	,404	,424	,445	,466	,488	,510	,532	,554	,
	577	,601	,625	,649	,675	,700	,727	,754	,781	,810	,
	839	,869	,900	,933	,966	,1000	
};
uint16_t FastAtan(int32_t x_circle, int32_t y_circle,int32_t x_delta,int32_t y_delta)
{	
	uint16_t i=0;
	int32_t x,y, angle=0;
	
	x=x_delta-x_circle;
	y=y_circle-y_delta;

	if(!x&& y >0) 
		angle=180;
	else if(!x&& y <0) 
		angle=0;	
	else if(!y&& x >0) 
		angle=270;
	else if(!y&& x <0) 
		angle=90;		
	else if(x > 0&& y > 0&&y <=x) 
	{
		angle=FastAtanTable[45]*y / x;
		if(angle==FastAtanTable[45])
			angle=225;
		else 
		{ 
			for(i=0;i<45;i++)
				if((angle>=FastAtanTable[i])&&(angle<FastAtanTable[i+1]))
				{
					angle=270-i;
					break;
				}	
		}
	}
	else if(x >0&& y >0&&y > x)
	{
		angle=FastAtanTable[45]*x / y;	
		for(i=0;i<45;i++)
			if((angle>=FastAtanTable[i])&&(angle<FastAtanTable[i+1]))
			{
				angle=180+i;
				break;
			}
	}
	else if(x <0&& y >0&&y >= -x)
	{
		angle=FastAtanTable[45]*(-x) / y;
		if(angle==FastAtanTable[45])
			angle=135;
		else 
		{ 		
			for(i=0;i<45;i++)
				if((angle>=FastAtanTable[i])&&(angle<FastAtanTable[i+1]))
				{
					angle=180-i;
					break;
				}
		}
	}
	else if(x <0&& y >0&&y < -x)
	{
		angle=FastAtanTable[45]*y / -x;	
		for(i=0;i<45;i++)
			if((angle>=FastAtanTable[i])&&(angle<FastAtanTable[i+1]))
			{
				angle=90+i;
				break;
			}
	}
	else if(x <0&& y <0&&y >=x) 
	{
		angle=FastAtanTable[45]*(-y)/-x ;
		if(angle==FastAtanTable[45])
			angle=45;
		else 
		{ 		
			for(i=0;i<45;i++)
				if((angle>=FastAtanTable[i])&&(angle<FastAtanTable[i+1]))
				{
					angle=90-i;
					break;
				}
		}
	}
	else if(x <0&& y <0&&y <x)
	{
		angle=FastAtanTable[45]*(-x)/-y ;
		
		for(i=0;i<45;i++)
			if((angle>=FastAtanTable[i])&&(angle<FastAtanTable[i+1]))
			{
				angle=i;
				break;
			}
	}	
	else if(x >0&& y <0&&-y >=x)
	{
		angle=FastAtanTable[45]*x / -y;
		if(angle==FastAtanTable[45])
			angle=315;
		else 
		{ 		
			for(i=0;i<45;i++)
				if((angle>=FastAtanTable[i])&&(angle<FastAtanTable[i+1]))
				{
					angle=360-i;
					break;
				}
		}
	} 
	else if(x >0&& y <0&&-y <x)
	{
		angle=FastAtanTable[45]*(-y) / x; 		
		for(i=0;i<45;i++)
			if((angle>=FastAtanTable[i])&&(angle<FastAtanTable[i+1]))
			{
				angle=270+i;
				break;
			}
	} 
	return angle;
}
int64_t LtPow(uint32_t d, uint32_t n)
{
	uint64_t s=1;
	int32_t i=0;

	for( i=0;i<n;i++)
		s *= d;
	return s;	
}

